#include "stdafx.h"
#include "StartingShotDecode.h"
#include <string.h>

void _encodeBase64(unsigned char *in, unsigned char *out)  
{  
    static const unsigned char encodeBase64Map[] =  
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  

    out[0] = encodeBase64Map[(in[0] >> 2) & 0x3F];  
    out[1] = encodeBase64Map[((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0F)];  
    out[2] = encodeBase64Map[((in[1] << 2) & 0x3C) | ((in[2] >> 6) & 0x03)];  
    out[3] = encodeBase64Map[in[2] & 0x3F];

    return;
}  

int StatingShotEncode(unsigned char *inbuf, int insize, unsigned char *outbuf, int outsize)  
{  
    int inpos = 0;
    int outpos = 0;

    while(inpos != insize) 
    {  
        if(inpos + 3 <= insize)
        {  
            if(outpos + 4 > outsize)  
            {
                return -1;  
            }
            _encodeBase64(inbuf + inpos, outbuf + outpos);  
            inpos += 3;  
            outpos += 4;  
        }  

        if(insize - inpos == 2)
        {  
            unsigned char tail[3] = {0};  
            tail[0] = *(inbuf + inpos);  
            tail[1] = *(inbuf + inpos + 1);  
            _encodeBase64(tail, outbuf + outpos);  
            *(outbuf + outpos + 3) = '=';  
            inpos += 2;  
            outpos += 4;  
        }  
        if(insize - inpos == 1)
        {  
            unsigned char tail[3] = {0};  
            tail[0] = *(inbuf + inpos);  
            _encodeBase64(tail, outbuf + outpos);  
            *(outbuf + outpos + 3) = '=';  
            *(outbuf + outpos + 2) = '=';  
            inpos += 1;  
            outpos += 4;  
        }  
    }  
    return outpos;  
}  

unsigned char decodeBase64Map(unsigned char a)  
{  
    if(a >= 'A' && a <= 'Z')  
    {
        return a - 'A';  
    }
    if(a >= 'a' && a <= 'z')  
    {
        return 26 + a - 'a';  
    }
    if(a >= '0' && a <= '9')  
    {
        return 52 + a - '0';  
    }
    if(a == '+')  
    {
        return 62;  
    }
    if(a == '/')  
    {
        return 63;  
    }
    if(a == '=')  
    {
        return 0;  
    }
    return -1;  
}  

void _decodeBase64(unsigned char *in, unsigned char *out)  
{  
    unsigned char map[4] = {0};

    map[0] = decodeBase64Map(in[0]);  
    map[1] = decodeBase64Map(in[1]);  
    map[2] = decodeBase64Map(in[2]);  
    map[3] = decodeBase64Map(in[3]);  

    out[0] = ((map[0] << 2) & 0xFC) | ((map[1] >> 4) & 0x03);  
    out[1] = ((map[1] << 4) & 0xF0) | ((map[2] >> 2) & 0x0F);  
    out[2] = ((map[2] << 6) & 0xC0) | ((map[3] >> 0) & 0x3F);  

    return;
}  

int base64decode(unsigned char *inbuf, int insize, unsigned char *outbuf, int outsize)  
{  
    int inpos = 0;
    int outpos = 0;  

    if(insize % 4)  
    {
        return -1;  
    }

    while(inpos != insize)
    {  
        if(outpos + 3 > outsize)  
        {
            return -1;  
        }
        _decodeBase64(inbuf + inpos, outbuf + outpos);  
        if(*(inbuf + inpos + 2) == '=') 
        {  
            outpos += 1;  
            break;  
        } 
        else if(*(inbuf + inpos + 3) == '=')
        {  
            outpos += 2;  
            break;  
        }
        else  
        {
            outpos += 3;  
        }
        inpos += 4;  
    }  
    return outpos;  
}  

char * StartingShotDecode(const char * szInput)
{
    char szOutput[PAGE_LEN] = {0};
    base64decode((unsigned char *)szInput, strlen(szInput), (unsigned char *)szOutput, PAGE_LEN);

    return szOutput;
}
